import os.path, math
import pygame
from game_object import game_object
import game_object_factory as obj_factory

class map:
    def __init__(self, mapFile, game):
        self.mapFile = mapFile
        self.game = game
        self.game_logic = self.game.game_logic
        self.config = {}
        self.update_surfs = []
        self.update_rects = []
        
        self.update_objs_list = []
        self.colliders = []
        
        #set up our map grid
        f = open(self.mapFile)
        content = f.readlines()
        f.close()
        self.terrainGrid = []
        self.objsGrid = []
        
        #do map configuration
        config_start = 0
        config_stop = 0
        map_terrain_start_line = 0
        map_terrain_stop_line = 0
        map_objs_start_line = 0
        map_objs_stop_line = 0
        for lnum in range(len(content)):
            line = content[lnum].replace("\n", "")
            if line == "config_start":
                config_start = lnum+1
            if line == "map_terrain_start":
                map_terrain_start_line = lnum+1
                config_stop = lnum-1
            if line == "map_terrain_stop":
                map_terrain_stop_line = lnum-1
            if line == "map_objects_start":
                map_objs_start_line = lnum+1
            if line == "map_objects_stop":
                map_objs_stop_line = lnum-1
        
        for lnum in range(config_start, config_stop+1):
            line = content[lnum].replace("\n", "")
            parts = line.split("=")
            self.config[parts[0]] = parts[1]
        if self.config['start_positions']:
            positions = self.config['start_positions']
            self.config['start_positions'] = []
            positions = positions.split(";")
            for pos in positions:
                x, y = pos.split(",")
                x = int(x)
                y = int(y)
                self.config['start_positions'].append((x*32,y*32))
            
        
        #map terrain
        for lnum in range(map_terrain_start_line, map_terrain_stop_line+1):
            line = content[lnum]
            self.terrainGrid.append(line.replace("\n", "").split(" "))
        
        #map objects
        for lnum in range(map_objs_start_line, map_objs_stop_line+1):
            line = content[lnum]
            self.objsGrid.append(line.replace("\n", "").split(" "))
        
        self.gridSize = {}
        self.gridSize['height'] = len(self.terrainGrid)
        self.gridSize['width'] = len(self.terrainGrid[0])
        self.width = self.gridSize['width'] * 32
        self.height = self.gridSize['height'] * 32
        
        #grab our sprite resources
        self.loadTerrainTiles()
        self.loadObjTiles()
        
        #set up our surface
        self.map_surf = pygame.Surface((self.gridSize['width']*32, self.gridSize['height']*32))
        self.map_rect = self.map_surf.get_rect()
        for row in range(len(self.terrainGrid)):
            for col in range(len(self.terrainGrid[row])):
                tile_number = int(self.terrainGrid[row][col])
                movX = self.terrainTileDefs[tile_number]['width']*col
                movY = self.terrainTileDefs[tile_number]['height']*row
                self.map_surf.blit(self.terrainTiles_surf, self.terrainTiles_rect.move(movX, movY), self.terrainTileDefs[tile_number]['rect'])
                
        for row in range(len(self.objsGrid)):
            for col in range(len(self.objsGrid[row])):
                tile_number = int(self.objsGrid[row][col])
                if tile_number > 0:
                    movX = self.objsTileDefs[tile_number]['width']*col
                    movY = self.objsTileDefs[tile_number]['height']*row
                    self.map_surf.blit(self.terrainTiles_surf, self.terrainTiles_rect.move(movX, movY), self.objsTileDefs[tile_number]['rect'])
                    
                    obj_surf = pygame.Surface((self.objsTileDefs[tile_number]['width'], self.objsTileDefs[tile_number]['height']))
                    obj_surf.blit(self.terrainTiles_surf, self.terrainTiles_rect, self.objsTileDefs[tile_number]['rect'])
                    cfg_name = os.path.join("data", "game_objects", self.objsTileDefs[tile_number]['name']+".cfg")
                    if os.path.isfile(cfg_name):
                        print "Making new %s" % self.objsTileDefs[tile_number]['name']
                        print "putting it at:", movX, movY
                        new_game_obj = obj_factory.get_object_by_classname(self.objsTileDefs[tile_number]['name'], self.game, cfg_name)
                    else:
                        new_game_obj = game_object(obj_surf)
                    new_game_obj.move(movX, movY)
                    if self.objsTileDefs[tile_number]['update']:
                        self.update_objs_list.append(new_game_obj)
                    if self.objsTileDefs[tile_number]['collider']:
                        self.colliders.append(new_game_obj)
        
        self.bg_surf = self.map_surf.copy()
        self.bg_rect = self.bg_surf.get_rect()
        self.screen_bg_surf = pygame.Surface(self.game.config.options['resolution'])
        self.screen_bg_surf.blit(self.bg_surf, self.bg_rect, pygame.Rect(0,0,800,600))
        
        print "NUMBER OF OBJECTS: ", len(self.update_objs_list)
    
    def draw_map_objs(self):
        for obj in self.update_objs_list:
            obj.update()
            newSurf = obj.image.copy()
            newSurf.blit(self.bg_surf, self.bg_rect, pygame.Rect(obj.rect))
            self.update_surfs.append(newSurf)
            self.update_rects.append(obj.rect)
            self.map_surf.blit(obj.image, obj.rect)
    
    def draw_objs(self, obj_list):
        for obj in obj_list:
            obj.update()
            newSurf = obj.image.copy()
            newSurf.blit(self.bg_surf, self.bg_rect, pygame.Rect(obj.rect))
            self.update_surfs.append(newSurf)
            self.update_rects.append(obj.rect)
            self.map_surf.blit(obj.image, obj.rect)
    
    def clear_objs(self):
        for i in range(len(self.update_surfs)):
            self.map_surf.blit(self.update_surfs[i], self.update_rects[i])
        self.update_surfs = []
        self.update_rects = []
    
    def loadObjTiles(self):
        f = open(os.path.join("data", "map_objs_defs.cfg"))
        content = f.readlines();
        self.objsTileDefs = {}
        for line in content:
            if not len(line):
                continue
            parts = line.replace("\n", "").split(";")
            left, top = parts[2].split(",")
            top = int(top)
            left = int(left)
            width = int(parts[3])
            height = int(parts[4])
            self.objsTileDefs[int(parts[0])] = {}
            self.objsTileDefs[int(parts[0])]['name'] = parts[1]
            self.objsTileDefs[int(parts[0])]['top'] = top
            self.objsTileDefs[int(parts[0])]['left'] = left
            self.objsTileDefs[int(parts[0])]['height'] = height
            self.objsTileDefs[int(parts[0])]['width'] = width
            self.objsTileDefs[int(parts[0])]['slowdown'] = float(parts[5])
            self.objsTileDefs[int(parts[0])]['tank_alpha'] = float(parts[6])
            self.objsTileDefs[int(parts[0])]['collider'] = int(parts[7])
            self.objsTileDefs[int(parts[0])]['update'] = int(parts[8])
            self.objsTileDefs[int(parts[0])]['rect'] = pygame.Rect(left, top, width, height)
        self.objsTiles_surf = pygame.image.load(os.path.join("data", "land_tiles.png"))
        self.objsTiles_surf.set_colorkey((255, 0, 255))
        self.objsTiles_rect = self.objsTiles_surf.get_rect()
    
    def loadTerrainTiles(self):
        f = open(os.path.join("data", "terrain_defs.cfg"))
        content = f.readlines();
        self.terrainTileDefs = {}
        for line in content:
            if not len(line):
                continue
            parts = line.replace("\n", "").split(";")
            left, top = parts[2].split(",")
            top = int(top)
            left = int(left)
            width = int(parts[3])
            height = int(parts[4])
            self.terrainTileDefs[int(parts[0])] = {}
            self.terrainTileDefs[int(parts[0])]['name'] = parts[1]
            self.terrainTileDefs[int(parts[0])]['top'] = top
            self.terrainTileDefs[int(parts[0])]['left'] = left
            self.terrainTileDefs[int(parts[0])]['height'] = height
            self.terrainTileDefs[int(parts[0])]['width'] = width
            self.terrainTileDefs[int(parts[0])]['slowdown'] = float(parts[5])
            self.terrainTileDefs[int(parts[0])]['tank_alpha'] = float(parts[6])
            self.terrainTileDefs[int(parts[0])]['collider'] = int(parts[7])
            self.terrainTileDefs[int(parts[0])]['rect'] = pygame.Rect(left, top, width, height)
        self.terrainTiles_surf = pygame.image.load(os.path.join("data", "land_tiles.png"))
        self.terrainTiles_surf.set_colorkey((255, 0, 255))
        self.terrainTiles_rect = self.terrainTiles_surf.get_rect()
    
    def get_slowdown_at(self, pos):
        (x, y) = pos
        tX = int(math.floor(x / 32))
        tY = int(math.floor(y / 32))
        if tX > self.gridSize['width']-1 or tY > self.gridSize['height']-1 or tX < 0 or tY < 0:
            return 5
        number = int(self.objsGrid[tY][tX])
        if number > 0:
            return self.objsTileDefs[number]['slowdown']
        else:
            number = int(self.terrainGrid[tY][tX])
            return self.terrainTileDefs[number]['slowdown']
    
    def get_alpha_at(self, pos):
        (x, y) = pos
        tX = int(math.floor(x / 32))
        tY = int(math.floor(y / 32))
        if tX > self.gridSize['width']-1 or tY > self.gridSize['height']-1 or tX < 0 or tY < 0:
            return 0
        number = int(self.terrainGrid[tY][tX])
        return self.terrainTileDefs[number]['tank_alpha']
        
